package com.pai4j.ugc.config.shardingJdbc;

import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.util.Collection;
import java.util.List;
import java.util.Properties;


/**
 * 自定义分片算法
 */
@Slf4j
public class CustomHashModShardingAlgorithm implements StandardShardingAlgorithm<String> {

    private Properties props;

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
        if (!shardingValue.getLogicTableName().equals("pai4j_moment_timeline")) {
            // 非目标表直接返回原表
            log.debug("非目标表，直接返回: {}", shardingValue.getLogicTableName());
            return shardingValue.getLogicTableName();
        }

        String user_id = shardingValue.getValue();
        int hash = user_id.hashCode();
        int shardingCount = Integer.parseInt(props.getProperty("sharding-count"));
        // 处理负值，确保结果为非负数
        int index = Math.abs(hash) % shardingCount;
        String suffix = "_" + index;

        log.debug("分片路由: user_id={}, hash={}, index={}, suffix={}", user_id, hash, index, suffix);
        log.debug("可用表名: {}", availableTargetNames);

        String targetTable = availableTargetNames.stream()
                .filter(table -> table.endsWith(suffix))
                .findFirst()
                .orElseThrow(() -> {
                    String errorMsg = String.format("分片路由失败: user_id=%s, 期望后缀=%s, 可用表=%s",
                            user_id, suffix, availableTargetNames);
                    log.error(errorMsg);
                    return new IllegalArgumentException(errorMsg);
                });

        log.debug("路由到表: {}", targetTable);
        return targetTable;
    }

    @Override
    public Collection<String> doSharding(Collection<String> collection,
                                         RangeShardingValue<String> rangeShardingValue) {
        return List.of();
    }

    @Override
    public void init(Properties props) {
        this.props = props;
    }

    @Override
    public String getType() {
        return "CUSTOM_HASH_MOD";
    }
}